/*
 * Copyright (c) 2024-2025 iSOFT INFRASTRUCTURE SOFTWARE CO., LTD.
 * easyAda is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#include <core/fault.h>
#include <core/schedule.h>
#include <core/task.h>
#include <caps/endpoint.h>
#include <uapi/errors.h>
#include <uapi/ipcbuffer.h>

void fault_report(void *_task, int type, unsigned long info0, unsigned long info1)
{
    endpoint_t *ep;
    tcb_t      *task = _task;

    assert(tcb_is_valid(task));

    task_set_fault(task, type);
    ep = task_get_faulthandler(task);

    task_set_flags(task, TASK_FBIT_REPORT);
    ipcbuffer_set_msgs(task_get_ipcbuffer(task), 2, task_get_id(task));
    endpoint_send(ep, msgtag_make(3, (unsigned short)type, 0), info0, info1, current());
}

void hardfault_handler(int type, unsigned long status, unsigned long addr)
{
    tcb_t *cur = current();

    tcb_get(cur);

    if (type == (int)FAULT_UNRECOVERY) {
        task_set_state(cur, TASK_INACTIVE);
        task_prepare_exit(cur);
    }
    fault_report(cur, type, status, addr);

    (void)tcb_put(cur);
    schedule();
}
